﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ObjectComposition
{
    public class CommandBinding
    {
        protected Command source;
        protected Command[] destinations;
        public CommandBinding(Command _source, params Command[] _destinations)
        {
            this.source = _source;
            this.source.AddBinding(this);
            this.destinations = _destinations;
        }
        public CommandBinding(Command _source, params Action[] _destinations)
        {
            this.source = _source;
            this.source.AddBinding(this);
            this.destinations = _destinations.Select(x => new Command { Action = x }).ToArray();
        }
        protected CommandBinding()
        {
        }
        public void Execute()
        {
            foreach (Command cmd in this.destinations)
                cmd.Execute();
        }
        public virtual void Execute(object parameter1)
        {
            foreach (Command cmd in this.destinations)
                cmd.Execute(parameter1);
        }
        public void Execute(object parameter1, object parameter2)
        {
            foreach (Command cmd in this.destinations)
                cmd.Execute(parameter1, parameter2);
        }
        public void Execute(object parameter1, object parameter2, object parameter3)
        {
            foreach (Command cmd in this.destinations)
                cmd.Execute(parameter1, parameter2, parameter3);
        }
    }
    public class CommandBinding<Type1, Type2> : CommandBinding
    {
        protected Func<Type1, Type2> transform;
        public CommandBinding(Command _source, Func<Type1, Type2> _transform, params Command[] _destinations)
            : base(_source, _destinations)
        {
            this.transform = _transform;
        }
        public CommandBinding(Command _source, Func<Type1, Type2> _transform, params Action[] _destinations)
            : base(_source, _destinations)
        {
            this.transform = _transform;
        }
        public override void Execute(object parameter1)
        {
            base.Execute(this.transform((Type1)parameter1));
        }
    }
    public class CommandBinding<Type> : CommandBinding
    {
        public CommandBinding(Command _source, params Action<Type>[] _destinations)
        {
            this.source = _source;
            this.source.AddBinding(this);
            this.destinations = _destinations.Select(x => new Command<Type> { Action = x }).ToArray();
        }
    }
}
